home *** CD-ROM | disk | FTP | other *** search
/ Business Shareware / Business Shareware.iso / start / gfxapps / pbmpl91d / pbmplus / newsrc / pnmcomp.c < prev    next >
C/C++ Source or Header  |  1993-01-08  |  4KB  |  178 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, David Koblas.                                     | */
  3. /* |   Permission to use, copy, modify, and distribute this software   | */
  4. /* |   and its documentation for any purpose and without fee is hereby | */
  5. /* |   granted, provided that the above copyright notice appear in all | */
  6. /* |   copies and that both that copyright notice and this permission  | */
  7. /* |   notice appear in supporting documentation.  This software is    | */
  8. /* |   provided "as is" without express or implied warranty.           | */
  9. /* +-------------------------------------------------------------------+ */
  10.  
  11. #include "pnm.h"
  12. #include "pgm.h"
  13. #include "ppm.h"
  14.  
  15. static gray    **alpha = NULL;
  16. static int    alphaCols, alphaRows;
  17. static xelval    alphaMax;
  18. static pixel    **image = NULL;
  19. static int    imageCols, imageRows, imageType;
  20. static xelval    imageMax;
  21. static int    InvertFlag = 0;
  22.  
  23. static char    *usage = 
  24.     "[-invert] [-xoff N] [-yoff N] [-alpha file] overlay [image] [output]";
  25.  
  26. main(argc, argv) 
  27. int    argc;
  28. char    *argv[];
  29. {
  30.     int    xoff = 0, yoff = 0;
  31.     FILE    *ifp, *ofp, *fp;
  32.     int    argn = 1;
  33.  
  34.     pnm_init(&argc, argv);
  35.  
  36.     while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
  37.         if (pm_keymatch(argv[argn], "-xoff", 2)) {
  38.             if (argn == argc || 
  39.                 sscanf(argv[++argn], "%d", &xoff) != 1)
  40.                 pm_usage(usage);
  41.         } else if (pm_keymatch(argv[argn], "-yoff", 2)) {
  42.             if (argn == argc || 
  43.                 sscanf(argv[++argn], "%d", &yoff) != 1)
  44.                 pm_usage(usage);
  45.         } else if (pm_keymatch(argv[argn], "-alpha", 2)) {
  46.             if (argn == argc || alpha != NULL) 
  47.                 pm_usage(usage);
  48.             
  49.             fp = pm_openr(argv[++argn]);
  50.             alpha = pgm_readpgm(fp, &alphaCols, 
  51.                         &alphaRows, &alphaMax);
  52.             pm_close(fp);
  53.         } else if (pm_keymatch(argv[argn], "-invert", 2)) {
  54.             InvertFlag = 1;
  55.         } else {
  56.             pm_usage(usage);
  57.         }
  58.         argn++;
  59.     }
  60.  
  61.     /*
  62.     **  Read the overlay file
  63.     */
  64.     if (argc == argn)
  65.         pm_usage(usage);
  66.     
  67.     fp = pm_openr(argv[argn++]);
  68.     image = pnm_readpnm(fp, &imageCols, &imageRows, &imageMax, &imageType);
  69.     pm_close(fp);
  70.  
  71.     /*
  72.     **  If there is an alphamap check to make sure it is the
  73.     **    same size as the image.
  74.     */
  75.     if (alpha != NULL && (imageCols!=alphaCols || imageRows!=alphaRows)) 
  76.         pm_error("Alpha map and Image are not the same size");
  77.  
  78.     /*
  79.     **  Now get the data file
  80.     */
  81.     if (argc != argn) 
  82.         ifp = pm_openr(argv[argn++]);
  83.     else 
  84.         ifp = stdin;
  85.  
  86.     /*
  87.     **  And the output file
  88.     */
  89.     if (argc != argn) 
  90.         ofp = pm_openw(argv[argn++]);
  91.     else 
  92.         ofp = stdout;
  93.  
  94.     /*
  95.     **  Composite the images together
  96.     */
  97.     composite(xoff, yoff, ifp, ofp);
  98.  
  99.     pm_close(ifp);
  100.     pm_close(ofp);
  101. }
  102.  
  103. composite(xoff, yoff, ifp, ofp)
  104. int    xoff, yoff;
  105. FILE    *ifp, *ofp;
  106. {
  107.     int    x, y, x0, y0;
  108.     int    r,g,b;
  109.     xelval    v, maxv, omaxv;
  110.     xel    *pixels;
  111.     double    f;
  112.     int    rows, cols, type, otype;
  113.  
  114.     pnm_readpnminit(ifp, &cols, &rows, &maxv, &type);
  115.  
  116.     pixels = pnm_allocrow(cols);
  117.  
  118.     pnm_writepnminit(ofp, cols, rows, maxv, type, 0);
  119.  
  120.     /*
  121.     **  Convert overlay image to common type & max
  122.     */
  123.     otype = (imageType < type) ? type : imageType;
  124.     omaxv = (imageMax  < maxv) ? maxv : imageMax;
  125.  
  126.     if (imageType != otype || imageMax != omaxv) {
  127.         pnm_promoteformat(image, imageCols, imageRows, 
  128.                 imageMax, imageType, omaxv, otype);
  129.         imageType = otype;
  130.         imageMax  = omaxv;
  131.     }
  132.  
  133.     for (y = 0; y < rows; y++) {
  134.         /*
  135.         **  Read a row and convert it to the output type
  136.         */
  137.         pnm_readpnmrow(ifp, pixels, cols, maxv, type);
  138.  
  139.         if (type != otype || maxv != omaxv)
  140.             pnm_promoteformatrow(pixels, cols, maxv, 
  141.                         type, omaxv, otype);
  142.  
  143.         /*
  144.         **  Now overlay the overlay with alpha (if defined)
  145.         */
  146.         for (x = 0; x < cols; x++) {
  147.             x0 = x - xoff;
  148.             y0 = y - yoff;
  149.  
  150.             if (x0 < 0 || x0 >= imageCols)
  151.                 continue;
  152.             if (y0 < 0 || y0 >= imageRows)
  153.                 continue;
  154.  
  155.             if (alpha == NULL) {
  156.                 f = 1.0;
  157.             } else {
  158.                 f = (double)alpha[y0][x0] / (double)alphaMax;
  159.                 if (InvertFlag) 
  160.                     f = 1.0 - f;
  161.             }
  162.  
  163.             r = PPM_GETR(pixels[x])     * (1.0 - f) + 
  164.                 PPM_GETR(image[y0][x0]) * f;
  165.             g = PPM_GETG(pixels[x])     * (1.0 - f) + 
  166.                 PPM_GETG(image[y0][x0]) * f;
  167.             b = PPM_GETB(pixels[x])     * (1.0 - f) + 
  168.                 PPM_GETB(image[y0][x0]) * f;
  169.  
  170.             PPM_ASSIGN(pixels[x], r, g, b);
  171.         }
  172.  
  173.         pnm_writepnmrow(ofp, pixels, cols, maxv, otype, 0);
  174.     }
  175.  
  176.     pnm_freerow(pixels);
  177. }
  178.